package com.neuresys.database.implstorage.indexeddbimpl;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONNumber;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;
import com.neuresys.database.databaseapi.DatabaseOpenHandler;
import com.neuresys.database.databaseapi.DatabaseSaveEvent;
import com.neuresys.database.databaseapi.DatabaseSaveHandler;
import com.neuresys.database.databaseapi.StoreDataService;
import com.neuresys.database.databaseimpl.jssqlite.SQLite;
import com.neuresys.database.databaseimpl.jssqlite.SQLiteDatabase;

public class IndexedDBStoreDataService implements StoreDataService {

	private static final String databaseName = "MyDatabase";
	private static final int databaseVersion = 1;
	private static final String databaseDecription = "MyDatabase description";

	public native static boolean isSupported()
	/*-{
		if (!$wnd.indexedDB) {
			return true;
		} else
			return false;
	}-*/;

	@Override
	public native void dropAllDatabase()
	/*-{
		$wnd.indexedDB = $wnd.indexedDB || $wnd.mozIndexedDB
				|| $wnd.webkitIndexedDB || $wnd.msIndexedDB;
		$wnd.IDBTransaction = $wnd.IDBTransaction || $wnd.webkitIDBTransaction
				|| $wnd.msIDBTransaction;
		$wnd.IDBKeyRange = $wnd.IDBKeyRange || $wnd.webkitIDBKeyRange
				|| $wnd.msIDBKeyRange;
		console.log($wnd.indexedDB);
		if ($wnd.indexedDB.deleteDatabase) {

			var dbreq = $wnd.indexedDB
					.deleteDatabase(@com.neuresys.database.implstorage.indexeddbimpl.IndexedDBStoreDataService::databaseName);
			dbreq.onsuccess = function(event) {

				var db = event.result;

			}

			dbreq.onerror = function(event) {

			}
		}
	}-*/;

	@Override
	public void dropDatabase(String name) {
		// TODO Auto-generated method stub

	}

	private native void getDatabase0(int name, DatabaseOpenHandler handler)
	/*-{
   $wnd.indexedDB = $wnd.indexedDB || $wnd.mozIndexedDB || $wnd.webkitIndexedDB || $wnd.msIndexedDB;
	$wnd.IDBTransaction = $wnd.IDBTransaction || $wnd.webkitIDBTransaction || $wnd.msIDBTransaction;
	$wnd.IDBKeyRange = $wnd.IDBKeyRange || $wnd.webkitIDBKeyRange || $wnd.msIDBKeyRange;
	var req = $wnd.indexedDB.open(@com.neuresys.database.implstorage.indexeddbimpl.IndexedDBStoreDataService::databaseName,
	 @com.neuresys.database.implstorage.indexeddbimpl.IndexedDBStoreDataService::databaseVersion);
    req.onsuccess = function (evt) {
       var db = this.result;
       var trans = db.transaction([@com.neuresys.database.implstorage.indexeddbimpl.IndexedDBStoreDataService::databaseName], "readwrite");
 	   var store = trans.objectStore(@com.neuresys.database.implstorage.indexeddbimpl.IndexedDBStoreDataService::databaseName);
 		var request = store.get(name);

    request.onsuccess = function(event) {
       if (request.result!=undefined)
       {
  		handler.@com.neuresys.database.databaseapi.DatabaseOpenHandler::onSucceed(Lcom/neuresys/database/databaseapi/DatabaseOpenEvent;)(@com.neuresys.database.databaseimpl.jssqlite.SQLiteDatabaseOpenEvent::new(Lcom/google/gwt/typedarrays/client/Uint8ArrayNative;)(request.result.value));
       }else{
       	var sqliteDatabase=@com.neuresys.database.databaseimpl.jssqlite.SQLiteDatabaseOpenEvent::new()();
     handler.@com.neuresys.database.databaseapi.DatabaseOpenHandler::onSucceed(Lcom/neuresys/database/databaseapi/DatabaseOpenEvent;)(sqliteDatabase); 	
        }
};


    };
    req.onerror = function (evt) {

    };

    req.onupgradeneeded = function (evt) {
      var store = evt.currentTarget.result.createObjectStore(
        @com.neuresys.database.implstorage.indexeddbimpl.IndexedDBStoreDataService::databaseName, { keyPath: 'id', autoIncrement: false });

      store.createIndex('name', 'name', { unique: false });
      store.createIndex('value', 'value', { unique: true });
    };

	}-*/;

	private native void insertOrCreateDatabase0(int hashname, String name,
			JavaScriptObject javaScriptObject)
	/*-{
		$wnd.indexedDB = $wnd.indexedDB || $wnd.mozIndexedDB
				|| $wnd.webkitIndexedDB || $wnd.msIndexedDB;
		$wnd.IDBTransaction = $wnd.IDBTransaction || $wnd.webkitIDBTransaction
				|| $wnd.msIDBTransaction;
		$wnd.IDBKeyRange = $wnd.IDBKeyRange || $wnd.webkitIDBKeyRange
				|| $wnd.msIDBKeyRange;
		name.@java.lang.Object::hashCode();
		var req = $wnd.indexedDB
				.open(
						@com.neuresys.database.implstorage.indexeddbimpl.IndexedDBStoreDataService::databaseName,
						@com.neuresys.database.implstorage.indexeddbimpl.IndexedDBStoreDataService::databaseVersion);
		req.onsuccess = function(evt) {
			// Better use "this" than "req" to get the result to avoid problems with
			// garbage collection.
			// db = req.result;
			var db = this.result;
			var trans = db
					.transaction(
							[ @com.neuresys.database.implstorage.indexeddbimpl.IndexedDBStoreDataService::databaseName ],
							"readwrite");
			var store = trans
					.objectStore(@com.neuresys.database.implstorage.indexeddbimpl.IndexedDBStoreDataService::databaseName);
			var key = hashname;
			store.put(javaScriptObject);
		};

		req.onerror = function(evt) {

		};

		req.onupgradeneeded = function(evt) {
			var store = evt.currentTarget.result
					.createObjectStore(
							@com.neuresys.database.implstorage.indexeddbimpl.IndexedDBStoreDataService::databaseName,
							{
								keyPath : 'id',
								autoIncrement : false
							});

			store.createIndex('name', 'name', {
				unique : false
			});
			store.createIndex('value', 'value', {
				unique : true
			});
		};

	}-*/;

	@Override
	public void getDatabase(String name, DatabaseOpenHandler handler) {
		getDatabase0(Math.abs(name.hashCode()), handler);
	};

	@Override
	public void insertOrCreateDatabase(String name, SQLite c,final DatabaseSaveHandler savehandle) {
		JSONObject obj = new JSONObject();
		obj.put("id", new JSONNumber(Math.abs(name.hashCode())));
		obj.put("name", new JSONString(name));
		obj.put("value", new JSONArray(c.getDatabase()));
		GWT.log(obj.toString());
		insertOrCreateDatabase0(name.hashCode(), name,
				obj.getJavaScriptObject());
		savehandle.onSucceed(new DatabaseSaveEvent());
	}

}
